<template>
  <div class="watermark-container" ref="watermarkRef">
    <slot />
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'

const props = defineProps({
  text: {
    type: String,
    default: '-'
  },
  fontSize: {
    type: Number,
    default: 12
  },
  color: {
    type: String,
    default: 'rgba(0, 0, 0, 0.1)'
  },
  rotate: {
    type: Number,
    default: -20
  },
  gap: {
    type: Array,
    default: () => [100, 100]
  },
  offset: {
    type: Array,
    default: () => [0, 0]
  }
})

const watermarkRef = ref(null)
let watermarkDiv = null
let observer = null

/**
 * 创建水印元素
 */
const createWatermark = () => {
  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')
  
  const devicePixelRatio = window.devicePixelRatio || 1
  const fontSize = props.fontSize * devicePixelRatio
  const font = `${fontSize}px Arial`
  
  ctx.font = font
  const metrics = ctx.measureText(props.text)
  const textWidth = metrics.width
  const textHeight = fontSize
  
  // 计算画布尺寸
  const canvasWidth = Math.max(textWidth, props.gap[0]) * devicePixelRatio
  const canvasHeight = Math.max(textHeight, props.gap[1]) * devicePixelRatio
  
  canvas.width = canvasWidth
  canvas.height = canvasHeight
  
  // 设置文本样式
  ctx.font = font
  ctx.fillStyle = props.color
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  
  // 旋转画布
  ctx.translate(canvasWidth / 2, canvasHeight / 2)
  ctx.rotate((props.rotate * Math.PI) / 180)
  
  // 绘制文本
  ctx.fillText(props.text, 0, 0)
  
  return canvas.toDataURL()
}

/**
 * 添加水印
 */
const addWatermark = () => {
  if (!watermarkRef.value) return
  
  removeWatermark()
  
  const watermarkUrl = createWatermark()
  
  watermarkDiv = document.createElement('div')
  // 动态计算容器高度
  const updateWatermarkHeight = () => {
    if (watermarkDiv && watermarkRef.value) {
      const containerHeight = Math.max(
        watermarkRef.value.scrollHeight,
        watermarkRef.value.offsetHeight,
        document.documentElement.scrollHeight,
        document.body.scrollHeight,
        window.innerHeight
      )
      watermarkDiv.style.height = `${containerHeight}px`
    }
  }

  watermarkDiv.style.cssText = `
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    min-height: 100vh;
    pointer-events: none;
    z-index: 9999;
    background-image: url(${watermarkUrl});
    background-repeat: repeat;
    background-position: ${props.offset[0]}px ${props.offset[1]}px;
  `

  watermarkRef.value.style.position = 'relative'
  watermarkRef.value.appendChild(watermarkDiv)

  // 初始设置高度
  setTimeout(() => {
    updateWatermarkHeight()
  }, 100)

  // 监听内容变化
  const resizeObserver = new ResizeObserver(() => {
    updateWatermarkHeight()
  })

  if (watermarkRef.value) {
    resizeObserver.observe(watermarkRef.value)
  }

  // 监听窗口大小变化
  window.addEventListener('resize', updateWatermarkHeight)

  // 存储观察器以便清理
  watermarkDiv._resizeObserver = resizeObserver
  watermarkDiv._updateHeight = updateWatermarkHeight
}

/**
 * 移除水印
 */
const removeWatermark = () => {
  if (watermarkDiv && watermarkDiv.parentNode) {
    // 清理监听器
    if (watermarkDiv._resizeObserver) {
      watermarkDiv._resizeObserver.disconnect()
    }
    if (watermarkDiv._updateHeight) {
      window.removeEventListener('resize', watermarkDiv._updateHeight)
    }

    watermarkDiv.parentNode.removeChild(watermarkDiv)
    watermarkDiv = null
  }
}

/**
 * 监听DOM变化，防止水印被删除
 */
const observeWatermark = () => {
  if (!watermarkRef.value || !window.MutationObserver) return
  
  observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (mutation.type === 'childList') {
        const removedNodes = Array.from(mutation.removedNodes)
        if (removedNodes.includes(watermarkDiv)) {
          // 水印被删除，重新添加
          nextTick(() => {
            addWatermark()
          })
        }
      }
    })
  })
  
  observer.observe(watermarkRef.value, {
    childList: true,
    subtree: true
  })
}

onMounted(() => {
  nextTick(() => {
    addWatermark()
    observeWatermark()
  })
})

onUnmounted(() => {
  removeWatermark()
  if (observer) {
    observer.disconnect()
    observer = null
  }
})

// 暴露方法供外部调用
defineExpose({
  refresh: addWatermark
})
</script>

<style scoped>
.watermark-container {
  position: relative;
  width: 100%;
  min-height: 100vh;
}
</style>
